import React, { useReducer, createContext, useContext, ReactNode, useMemo } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { HomeOutlined } from '@ant-design/icons';

interface Pane {
    key: string;
    label: string;
    closable?: boolean;
    langID?: string;
    icon: any;
}

interface State {
    panes: Pane[];
}
interface NavOptions {
    label: string;
    key: string;
    langID?: string;
    options?: any;
}
interface INavContext extends State {
    nav: (options: NavOptions) => void;
    closePane: (key: string) => void;
    navTo: (key: string) => void;
}

interface Action {
    type: string;
    [key: string]: any;
}

export const NavContext = createContext<INavContext>({
    panes: [],
    nav(options: NavOptions) {},
    closePane(key: string) {},
    navTo(key: string) {},
});

function reducer(state: State, action: Action) {
    switch (action.type) {
        case 'addPane': {
            const { key, label, langID } = action;
            const index = state.panes.findIndex((item) => item.key === key);
            if (index === -1) {
                const pane = {
                    key,
                    label,
                    langID,
                };
                return {
                    ...state,
                    panes: [...state.panes, pane],
                };
            } else {
                return state;
            }
        }
        case 'closePane': {
            return {
                ...state,
                panes: action.panes,
            };
        }
        default: {
            throw Error('Unknown action: ' + action.type);
        }
    }
}
// 路由并且打开或跳转到对应的页签
export function NavProvider({ children }: { children: ReactNode }) {
    const navigate = useNavigate();
    const { pathname } = useLocation();

    /**
     * 使用useReducer
     */
    const [state, dispatch] = useReducer(reducer, {
        panes: [
            {
                langID: 'menu.home',
                key: 'home',
                label: '首页',
                closable: false,
                icon: <HomeOutlined />,
            },
        ],
    });

    const value = useMemo(() => {
        /**
         * 跳转
         * @param {*} param0
         */
        function nav({ label, key, langID, options }: NavOptions) {
            dispatch({
                type: 'addPane', // 增加面板
                label, // 名称
                key, // key
                langID,
            });
            navigate(key, options);
        }

        // 关闭面板页签
        function closePane(key: string) {
            const index = state.panes.findIndex((item: Pane) => item.key === key);
            const newPanes = [...state.panes.filter((item: Pane) => item.key !== key)];
            const activePaneKey = pathname.replace(/\/portal\/?/i, '') || 'home';

            if (key === activePaneKey) {
                // 关闭当前面板页签时打开前一个面板页签
                const newKey = Math.max(index - 1, 0);
                const pane = newPanes[newKey];

                nav({
                    key: pane.key,
                    langID: pane.langID,
                    label: pane.label,
                    options: {
                        replace: true,
                    },
                });
            }
            dispatch({
                type: 'closePane',
                panes: newPanes,
            });
        }

        // 打开面板页签
        function navTo(key: string) {
            const pane = state.panes.find((item: Pane) => item.key === key);
            if (pane) {
                nav({
                    langID: pane.langID,
                    label: pane.label,
                    key,
                    options: {
                        replace: true,
                    },
                });
            }
        }

        return {
            ...state,
            nav,
            closePane,
            navTo,
        };
    }, [state, navigate, pathname]);

    return <NavContext.Provider value={value}>{children}</NavContext.Provider>;
}

export function useNav() {
    return useContext(NavContext);
}
